# projects/serializers.py
from rest_framework import serializers
from django.contrib.auth import get_user_model
from .models import Project, ProjectAttachment
from accounts.models import Laboratory

User = get_user_model()


class ProjectAttachmentSerializer(serializers.ModelSerializer):
    """项目附件序列化器"""
    
    url = serializers.SerializerMethodField()
    uploaded_by_name = serializers.CharField(source='uploaded_by.full_name', read_only=True)
    
    class Meta:
        model = ProjectAttachment
        fields = [
            'id', 'name', 'size', 'content_type', 
            'uploaded_at', 'uploaded_by_name', 'url'
        ]
        read_only_fields = ['id', 'uploaded_at', 'uploaded_by_name', 'url']
    
    def get_url(self, obj):
        """获取文件访问URL"""
        request = self.context.get('request')
        if obj.file and request:
            return request.build_absolute_uri(obj.file.url)
        return None


class ProjectSerializer(serializers.ModelSerializer):
    """项目序列化器"""
    
    attachments = ProjectAttachmentSerializer(many=True, read_only=True)
    laboratory_name = serializers.CharField(read_only=True)
    
   
    class Meta:
        model = Project
        fields = [
            'id', 'name', 'description', 'status', 'crop_type',
            'location', 'start_date', 'end_date', 
            'budget', 'objectives', 'manager', 'laboratory', 'laboratory_name', 
            'attachments', 'created_at', 'updated_at'
        ]
        read_only_fields = [
            'id', 'created_at', 'updated_at', 'laboratory_name', 
            'attachments'
        ]
    
    def validate(self, data):
        """数据验证"""
        start_date = data.get('start_date')
        end_date = data.get('end_date')
        
        # 验证日期逻辑
        if start_date and end_date and start_date > end_date:
            raise serializers.ValidationError("开始日期不能晚于结束日期")
        
        # 验证预算
        budget = data.get('budget')
        if budget is not None and budget < 0:
            raise serializers.ValidationError("项目预算不能为负数")
            
        return data
    
    def validate_objectives(self, value):
        """验证项目目标"""
        if not isinstance(value, list):
            raise serializers.ValidationError("项目目标必须是列表格式")
        
        if len(value) == 0:
            raise serializers.ValidationError("至少需要设置一个项目目标")
            
        for objective in value:
            if not isinstance(objective, str) or not objective.strip():
                raise serializers.ValidationError("项目目标不能为空")
                
        return value
    
    def create(self, validated_data):
        """创建项目"""
        request = self.context.get('request')
        if request and request.user:
            # 设置默认实验室为用户所属实验室
            if not validated_data.get('laboratory') and request.user.laboratory:
                validated_data['laboratory'] = request.user.laboratory
        
        return super().create(validated_data)


class CreateProjectSerializer(serializers.ModelSerializer):
    """创建项目序列化器"""
    
    # 附件上传字段
    attachments = serializers.ListField(
        child=serializers.FileField(),
        required=False,
        allow_empty=True,
        write_only=True
    )
    
    class Meta:
        model = Project
        fields = [
            'name', 'description', 'crop_type', 'location', 
            'start_date', 'end_date', 'budget', 'objectives', 'manager', 'attachments'
        ]
    
    def validate_objectives(self, value):
        """验证项目目标"""
        # 如果是字符串，尝试解析为JSON
        if isinstance(value, str):
            try:
                import json
                value = json.loads(value)
            except (json.JSONDecodeError, ValueError):
                raise serializers.ValidationError("项目目标格式错误")
        
        if not isinstance(value, list):
            raise serializers.ValidationError("项目目标必须是列表格式")
        
        if len(value) == 0:
            raise serializers.ValidationError("至少需要设置一个项目目标")
            
        for objective in value:
            if not isinstance(objective, str) or not objective.strip():
                raise serializers.ValidationError("项目目标不能为空")
                
        return value
    
    def validate_start_date(self, value):
        """验证开始日期格式"""
        if value:
            import re
            if not re.match(r'^\d{4}-\d{2}$', value):
                raise serializers.ValidationError("日期格式错误，请使用 YYYY-MM 格式")
        return value
    
    def validate_end_date(self, value):
        """验证结束日期格式"""
        if value:
            import re
            if not re.match(r'^\d{4}-\d{2}$', value):
                raise serializers.ValidationError("日期格式错误，请使用 YYYY-MM 格式")
        return value
    
    def validate(self, data):
        """数据验证"""
        start_date = data.get('start_date')
        end_date = data.get('end_date')
        
        # 验证日期逻辑（比较字符串格式的日期）
        if start_date and end_date and start_date > end_date:
            raise serializers.ValidationError("开始日期不能晚于结束日期")
        
        budget = data.get('budget')
        if budget is not None and budget < 0:
            raise serializers.ValidationError("项目预算不能为负数")
            
        return data
    
    def create(self, validated_data):
        """创建项目和附件"""
        attachments_data = validated_data.pop('attachments', [])
        request = self.context.get('request')
        
        # 设置项目实验室
        if request and request.user:
            if request.user.laboratory:
                validated_data['laboratory'] = request.user.laboratory
        
        # 创建项目
        project = Project.objects.create(**validated_data)
        
        # 创建附件
        for attachment_file in attachments_data:
            ProjectAttachment.objects.create(
                project=project,
                name=attachment_file.name,
                file=attachment_file,
                size=attachment_file.size,
                content_type=attachment_file.content_type,
                uploaded_by=request.user if request else None
            )
        
        return project


class UpdateProjectSerializer(serializers.ModelSerializer):
    """更新项目序列化器"""
    
    # 新附件上传字段
    new_attachments = serializers.ListField(
        child=serializers.FileField(),
        required=False,
        allow_empty=True,
        write_only=True
    )
    
    class Meta:
        model = Project
        fields = [
            'name', 'description', 'status', 'crop_type', 'location', 
            'start_date', 'end_date', 'budget', 'objectives', 'manager', 'new_attachments'
        ]
        extra_kwargs = {
            'name': {'required': False},
            'description': {'required': False},
            'status': {'required': False},
            'location': {'required': False},
            'budget': {'required': False},
            'objectives': {'required': False},
            'manager': {'required': False},
        }
    
    def validate_start_date(self, value):
        """验证开始日期格式"""
        if value:
            import re
            if not re.match(r'^\d{4}-\d{2}$', value):
                raise serializers.ValidationError("日期格式错误，请使用 YYYY-MM 格式")
        return value
    
    def validate_end_date(self, value):
        """验证结束日期格式"""
        if value:
            import re
            if not re.match(r'^\d{4}-\d{2}$', value):
                raise serializers.ValidationError("日期格式错误，请使用 YYYY-MM 格式")
        return value
    
    def validate(self, data):
        """数据验证"""
        start_date = data.get('start_date')
        end_date = data.get('end_date')
        
        # 如果只更新其中一个日期，需要与现有数据比较
        if start_date or end_date:
            instance = getattr(self, 'instance', None)
            if instance:
                actual_start = start_date or instance.start_date
                actual_end = end_date or instance.end_date
                if actual_start > actual_end:
                    raise serializers.ValidationError("开始日期不能晚于结束日期")
        
        budget = data.get('budget')
        if budget is not None and budget < 0:
            raise serializers.ValidationError("项目预算不能为负数")
            
        return data
    
    def update(self, instance, validated_data):
        """更新项目和附件"""
        new_attachments_data = validated_data.pop('new_attachments', [])
        request = self.context.get('request')
        
        # 更新项目基本信息
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        
        # 添加新附件
        for attachment_file in new_attachments_data:
            ProjectAttachment.objects.create(
                project=instance,
                name=attachment_file.name,
                file=attachment_file,
                size=attachment_file.size,
                content_type=attachment_file.content_type,
                uploaded_by=request.user if request else None
            )
        
        return instance


class AttachmentUploadSerializer(serializers.Serializer):
    """附件上传序列化器"""
    
    attachments = serializers.ListField(
        child=serializers.FileField(),
        allow_empty=False
    )
    
    def create(self, validated_data):
        """批量创建附件"""
        project = self.context['project']
        request = self.context['request']
        attachments_data = validated_data['attachments']
        
        created_attachments = []
        for attachment_file in attachments_data:
            attachment = ProjectAttachment.objects.create(
                project=project,
                name=attachment_file.name,
                file=attachment_file,
                size=attachment_file.size,
                content_type=attachment_file.content_type,
                uploaded_by=request.user
            )
            created_attachments.append(attachment)
        
        return created_attachments